package drds.plus.executor.function.scalar;

import drds.plus.executor.ExecuteContext;
import drds.plus.executor.ExecutorException;
import drds.plus.executor.function.ExtraFunction;
import drds.plus.executor.function.FunctionException;
import drds.plus.executor.row_values.RowValues;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.FunctionType;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.extra_function.IExtraFunction;

import java.util.List;

/**
 * map是分发过程，reduce是合并过程。<br/>
 * 分发和合并都是在计算节点上进行的（计算节点在客户端内，包含数据节点、合并节点和客户端节点） 其余的与map reduce模式一致。
 */
public abstract class ScalarFunction extends ExtraFunction implements IExtraFunction {

    public FunctionType getFunctionType() {
        return FunctionType.scalar;
    }

    public String getDataBaseFunction() {
        return function.getColumnName();
    }

    protected abstract Object compute(ExecuteContext executeContext, Object[] args);

    public Object scalarCalucate(ExecuteContext executeContext, RowValues rowData) {
        // 当前function需要的args 有些可能是函数，也有些是其他的一些数据
        List<Object> argsList = getMapArgList(function);
        // 函数的input参数
        Object[] inputArg = new Object[argsList.size()];
        int index = 0;
        for (Object funcArg : argsList) {
            inputArg[index] = getArgValue(executeContext, funcArg, rowData);
            index++;
        }

        if (this instanceof ScalarFunction) {
            try {
                return this.compute(executeContext, inputArg);
            } catch (ArrayIndexOutOfBoundsException e) {
                throw new FunctionException("Incorrect parameter count in the call to native function '" + this.function.getFunctionName() + "'");
            }
        } else {
            throw new ExecutorException("impossible");
        }
    }

    public void clear() {

    }

}
